using System;
using DecisionMaking.Domain;
using System.Collections.Generic;
using DecisionMaking.BusinessLogic.Model;

namespace DecisionMaking.BusinessLogic
{
	/// <summary>
	/// Deals with CRUD operations regarding Environments and their components 
	/// </summary>
	public interface IEnvironmentManager
	{
		/// <summary>
		/// Creates or updates the specified environment in persistent storage 
		/// </summary>
		/// <param name="model">
		/// A <see cref="EnvironmentModel"/>
		/// </param>
		/// <exception cref="DuplicateEnvironmentNameException">If an environment with the specified name already exists</exception>
		DecisionMaking.Domain.Environment SaveEnvironment(EnvironmentModel model);		
		
		/// <summary>
		/// Retrieves all environments created by the specified account 
		/// </summary>
		/// <param name="accountId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <returns>
		/// A <see cref="IList<DecisionMaking.Domain.Environment>"/>
		/// </returns>
		IList<DecisionMaking.Domain.Environment> GetEnvironments(int accountId);	
				
		/// <summary>
		/// Returns the environment with the specified id or throws EntityNotFoundException if no such environment exists  
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <returns>
		/// A <see cref="DecisionMaking.Domain.Environment"/>
		/// </returns>
		DecisionMaking.Domain.Environment GetEnvironment(int environmentId);
				
		/// <summary>
		/// Gets all CueAttributes associated with the specified environment 
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <returns>
		/// A <see cref="IList<CueAttribute>"/>
		/// </returns>
		IList<CueAttribute> GetCueAttributes(int environmentId);		
		
		/// <summary>
		/// Adds the specified CueAttribute to the specified Environment 
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <param name="model">
		/// A <see cref="CueAttributeModel"/>
		/// </param>
		/// <exception cref="DuplicateCueAttributeNameException">If two cue attributes have the same name</exception>
		CueAttribute AddCueAttribute(CueAttributeModel model);
		
		/// <summary>
		/// Deletes the specified CueAttribute 
		/// </summary>
		/// <param name="id">
		/// A <see cref="System.Int32"/>
		/// </param>
		void RemoveCueAttribute(int id);
		
		/// <summary>
		/// Return a list of Cues for the specified environment
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <returns>
		/// A <see cref="IList<Cue>"/>
		/// </returns>
		IList<Cue> GetCues(int environmentId);		
		
		/// <summary>
		/// Adds the specified Cue to the specified Environment 
		/// </summary>
		/// <param name="model">
		/// A <see cref="CueModel"/>
		/// </param>
		/// <returns>
		/// A <see cref="Cue"/>
		/// </returns>
		/// <exception cref="DuplicateCueNameException">If two cues have the same name</exception>
		Cue AddCue(CueModel model);	
		
		/// <summary>
		/// Deletes the specified Cue from the specified Environment 
		/// </summary>
		/// <param name="id">
		/// A <see cref="System.Int32"/>
		/// </param>
		void RemoveCue(int id);
		
		/// <summary>
		/// Creates or updates the specified Candidates in the specified Environment 
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <param name="candidates">
		/// A <see cref="IList<Candidate>"/>
		/// </param>
		/// <exception cref="DuplicateCandidateNameException">If two candidate have the same name</exception>
		void SaveCandidates(int environmentId, IList<Candidate> candidates);

		IList<Candidate> GetCandidates(int environmentId);
		
		/// <summary>
		/// Deletes all existing agents, if any, and creates new agents with random CandidateCueValues 
		/// </summary>
		/// <param name="environmentId">
		/// A <see cref="System.Int32"/>
		/// </param>
		/// <param name="amount">
		/// A <see cref="System.Int32"/>
		/// </param>
		void GenerateAgents(int environmentId, int amount);

				
		
	}
}

